#pragma once

typedef void (*callback_t)();

template<class T>
class Thread
{
public:
    Thread(callback_t cb)
        :cb_(cb), isrunning_(false), start_timestamp_(0)
    {
        tid_ = 0;
    }
    
    void Join()
    {
        pthread_join(tid_, nullptr);
        isrunning_ = false;
    }

    static void* Routine(void* arg)
    {
        Thread* thread = static_cast<Thread*>(arg);
        thread->Entry();
        return nullptr;
    }

    void Run()
    {
        name_= "thread"+ std::to_string(++count);
        start_timestamp_ = time(nullptr);
        isrunning_ = true;
        pthread_create(&tid_, nullptr, Routine, this);
    }

    void Entry()
    {
        cb_();
    }

    std::string Name() const
    {
        return name_;
    }

    uint64_t StartTimestamp() const
    {
        return start_timestamp_;
    }

    bool IsRunning() const
    {
        return isrunning_;
    }
private:
    pthread_t tid_;
    std::string name_;
    uint64_t start_timestamp_;
    bool isrunning_;
    int count=0;
    callback_t cb_;
};